package com.wym.charging.controller;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wym.charging.common.JwtUtil;
import com.wym.charging.common.Result;
import com.wym.charging.dto.*;
import com.wym.charging.entity.User;
import com.wym.charging.service.UserService;
import com.wym.charging.vo.UserVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.HashMap;
import java.util.Objects;
import java.util.UUID;

/**
 * @author WangYimin 2024年12月06日 16:42:08
 */
@RestController
@RequestMapping("/user")
@Tag(name = "用户接口")
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${ImgPath}")
    private String imgPath;

    @PostMapping("/register")
    @Operation(summary = "用户注册")
    public Result<String> register(@RequestBody UserDto userDto) throws Exception {
        if (StringUtils.isEmpty(userDto.getUsername()) || userDto.getUsername().length() < 3) {
           throw new Exception("用户名不能为空且长度最少为3位");
        }
        if (StringUtils.isEmpty(userDto.getPassword()) || userDto.getPassword().length() < 8) {
            throw new Exception("密码不能为空且长度最少为8位");
        }
        if (!userDto.getPassword().equals(userDto.getConfirmPassword())) {
            throw new Exception("密码和重复密码不一致");
        }
        User one = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, userDto.getUsername()));
        if (one != null) {
            throw new Exception("用户名已被注册");
        }
        User user = new User();
        user.setUsername(userDto.getUsername());
        user.setPassword(DigestUtils.md5Hex(userDto.getPassword()));
        userService.save(user);
        return Result.success("注册成功");
    }

    @PostMapping("/login")
    @Operation(summary = "用户登录")
    public Result<UserVo> login(@RequestBody LoginDto loginDto) throws Exception {
        if (StringUtils.isEmpty(loginDto.getUsername()) || StringUtils.isEmpty(loginDto.getPassword())) {
            throw new Exception("用户名和密码不能为空");
        }
        User user1 = userService.getBaseMapper().selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, loginDto.getUsername()));
        if (user1 == null) {
            throw new Exception("用户不存在");
        }
        if (!user1.getPassword().equals(DigestUtils.md5Hex(loginDto.getPassword()))) {
            throw new Exception("密码错误");
        }
        user1.setPassword(null);
        String jsonString = JSON.toJSONString(user1);
        HashMap<String, Object> claims = new HashMap<>();
        claims.put("user", jsonString);
        String token = JwtUtil.generateToken(claims);
        redisTemplate.opsForValue().set(token, user1, Duration.ofMillis(JwtUtil.jwtExpirationMs));
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user1, userVo);
        userVo.setToken(token);
        return Result.success("登录成功", userVo);
    }

    @PostMapping("/recharge")
    @Operation(summary = "充值余额")
    public Result<User> Recharge(@RequestBody RechargeRequestDto rechargeRequestDto) throws Exception {
        if (rechargeRequestDto.getUserId() == null || rechargeRequestDto.getUserId() <= 0) {
            throw new Exception("用户id不能为空");
        }
        if (rechargeRequestDto.getAmount() == null || rechargeRequestDto.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new Exception("充值金额不能为空且必须大于0");
        }
        User recharge = userService.recharge(rechargeRequestDto.getUserId(), rechargeRequestDto.getAmount());
        return Result.success("充值成功", recharge);
    }

    @PostMapping("/get-user-info")
    @Operation(summary = "获取用户信息")
    public Result<User> getUserInfo(Long userId) throws Exception {
        if (userId == null || userId <= 0) {
            throw new Exception("用户id不能为空");
        }
        User user = userService.getById(userId);
        if (user == null) {
            throw new Exception("用户不存在");
        }
        return Result.success(user);
    }

    @Operation(summary = "获取头像")
    @GetMapping("/get-user-avatar")
    public void getHeadImg(Integer userId, HttpServletResponse response) throws Exception {
        if (userId == null || userId <= 0) {
            throw new Exception("用户id不能为空");
        }
        User user = userService.getById(userId);
        if (user == null) {
            throw new Exception("用户不存在");
        }

        if (StringUtils.isNotBlank(user.getUserAvatar())) {
            File imgFile = new File(user.getUserAvatar());
            System.out.println(imgFile.getName());
            if(!imgFile.exists()){
                throw new Exception("无效的头像路径！");
            }
            try (InputStream ins = new FileInputStream(imgFile)){
                response.setContentType("image/jpeg");
                OutputStream os = response.getOutputStream();
                byte[] buf = new byte[1024];
                int n;
                while ((n = ins.read(buf )) != -1){
                    os.write(buf,0,n);
                }
                os.flush();
            } catch (IOException e) {
                throw new Exception("读取头像失败！");
            }
        }
    }

    @Operation(summary = "修改用户密码")
    @PostMapping("/modify-user-password")
    public Result<String> modifyUserPassword(@RequestBody ModifyUserPasswordDto modifyUserPasswordDto, HttpServletRequest request) throws Exception {
        String token = request.getHeader(HttpHeaders.AUTHORIZATION);
        Object o = redisTemplate.opsForValue().get(token);
        String jsonString = JSON.toJSONString(o);
        User user = JSON.parseObject(jsonString, User.class);
        if (!Objects.equals(user.getId(), modifyUserPasswordDto.getId())) {
            throw new Exception("token和当前用户不一致，请重新登陆");
        }
        if (StringUtils.isEmpty(modifyUserPasswordDto.getOldPassword()) || StringUtils.isEmpty(modifyUserPasswordDto.getPassword()) || StringUtils.isEmpty(modifyUserPasswordDto.getConfirmPassword())) {
            throw new Exception("密码不能为空");
        }
        if (!modifyUserPasswordDto.getPassword().equals(modifyUserPasswordDto.getConfirmPassword())) {
            throw new Exception("密码和重复密码不一致");
        }
        //验证旧密码是否正确
        User user1 = userService.getById(modifyUserPasswordDto.getId());
        if (!user1.getPassword().equals(DigestUtils.md5Hex(modifyUserPasswordDto.getOldPassword()))) {
            throw new Exception("旧密码错误");
        }
        //新密码位数限制
        if (modifyUserPasswordDto.getPassword().length() < 8) {
            throw new Exception("密码长度最少为8位");
        }
        //新密码不和旧密码相同
        if (modifyUserPasswordDto.getPassword().equals(modifyUserPasswordDto.getOldPassword())) {
            throw new Exception("新密码不能和旧密码相同");
        }
        User user2 = new User();
        user2.setId(modifyUserPasswordDto.getId());
        user2.setPassword(DigestUtils.md5Hex(modifyUserPasswordDto.getPassword()));
        userService.updateById(user2);
        return Result.success("修改密码成功");
    }


    @PostMapping("/upload-user-avatar")
    @Operation(summary = "上传头像")
    public String uploadHeadImg(Integer userId, MultipartFile headImg) throws Exception {
        //如果保存图像的文件夹不存在，创建文件夹
        File path = new File(imgPath);
        if(!path.exists()){
            path.mkdirs();
        }
        if(headImg.isEmpty())
            throw new Exception("没有上传头像");
        //验证上传的是jpg图像
        if(!"image/jpeg".equals(headImg.getContentType()))
            throw new Exception("上传的不是jpg图像！");
        //取得头像文件的原始文件名
        String originalFilename = headImg.getOriginalFilename();
        //保存时的图像文件名为UUID名称，以防止图像重名
        String filename = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
        File destFile = new File(path,filename);
        try {
            //保存图像
            headImg.transferTo(destFile);
            //更新用户表中的图像
            String headImgPath = imgPath+filename;
            User user = new User();
            user.setId(userId);
            user.setUserAvatar(headImgPath);
            userService.updateById(user);
        } catch (IOException e) {
            throw new Exception("文件上传异常，请稍后再试！");
        }
        return "头像上传成功！";
    }

    @PostMapping("/buy-monthly-subscription")
    @Operation(summary = "购买包月")
    public Result<String> buyMonthlySubscription(@RequestBody BuyMonthlySubscriptionDto buyMonthlySubscriptionDto) throws Exception {
        if (buyMonthlySubscriptionDto.getUserId() == null || buyMonthlySubscriptionDto.getUserId() <= 0) {
            throw new Exception("用户id不能为空");
        }
        userService.buyMonthlySubscription(buyMonthlySubscriptionDto);
        return Result.success("购买成功");
    }

    @Operation(summary = "删除用户")
    @DeleteMapping("/delete-user")
    public Result<String> deleteUser(Long userId, HttpServletRequest request) throws Exception {
        String token = request.getHeader(HttpHeaders.AUTHORIZATION);
        Object o = redisTemplate.opsForValue().get(token);
        String jsonString = JSON.toJSONString(o);
        User user = JSON.parseObject(jsonString, User.class);
        if (user == null || !"admin".equals(user.getUsername())) {
            throw new Exception("没有权限删除用户");
        }
        if (userId == null || userId <= 0) {
            throw new Exception("用户id不能为空");
        }
        userService.removeById(userId);
        return Result.success("删除成功");
    }

}
